#include "render.h"
//#include "utils.h"

int const SCREEN_WIDTH = 640;
int const SCREEN_HEIGHT = 480;
int const SCREEN_BPP = 32;

SDL_Surface *screen;

int SE_initgraphics()
{



	if((SDL_Init( SDL_INIT_VIDEO )) < 0 )
	{
		printf("error, no inicia video");
		return 0;
	}
	

	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);

	
	if((screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_OPENGL)) < 0)
	{
		printf("error, no inicia modo gráfico");
		return 0;
	}
	

	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

	glPushAttrib(GL_ENABLE_BIT);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);
	glEnable( GL_TEXTURE_2D );

	/* This allows alpha blending of 2D textures with the scene */
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	//glBlendFunc( GL_SRC_ALPHA, GL_ONE );

	
	glViewport( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

	
	//glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );



	return 1;
	
}

void enable2d()							
{

	glMatrixMode(GL_PROJECTION);				
	glPushMatrix();							
	glLoadIdentity();						
	glOrtho(0, (GLdouble)SCREEN_WIDTH, (GLdouble)SCREEN_HEIGHT, 0, -1000, 1000);				
	glMatrixMode(GL_MODELVIEW);					
	glPushMatrix();							
	glLoadIdentity();

	
				
}

void disable2d()							
{
	glMatrixMode( GL_PROJECTION );					
	glPopMatrix();							
	glMatrixMode( GL_MODELVIEW );					
	glPopMatrix();							
}

void SE_clearscreen(float r,float g,float b,float a)
{
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glClearColor(r,g,b,a);

}


GLuint loadTexture(SDL_Surface *surface)
{
	GLuint texture;
	int w, h;
	SDL_Surface *image;
	SDL_Rect area;
	Uint32 saved_flags;
	Uint8  saved_alpha;

	//verifica si el ancho de la imagen es potencia de 2
	if(SE_utils_powerof2(surface->w) == 0) printf("warning: image width is not a power of 2\n");
    	//verifica si el alto de la imagen es potencia de 2
	if(SE_utils_powerof2(surface->h) == 0) printf("warning: image height is not a power of 2\n");

	w = surface->w;
	h = surface->h;
	
	
	image = SDL_CreateRGBSurface(
			SDL_SWSURFACE,
			w, h,
			32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
			0x000000FF, 
			0x0000FF00, 
			0x00FF0000, 
			0xFF000000
#else
			0xFF000000,
			0x00FF0000, 
			0x0000FF00, 
			0x000000FF
#endif
		       );
	if ( image == NULL ) {
		return 0;
	}

	/* Save the alpha blending attributes */
	saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
	saved_alpha = surface->format->alpha;
	if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
		SDL_SetAlpha(surface, 0, 0);
	}

	/* Copy the surface into the GL texture image */
	area.x = 0;
	area.y = 0;
	area.w = surface->w;
	area.h = surface->h;
	SDL_BlitSurface(surface, &area, image, &area);

	/* Restore the alpha blending attributes */
	if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
		SDL_SetAlpha(surface, saved_flags, saved_alpha);
	}

	/* Create an OpenGL texture for the image */
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D,
		     0,
		     GL_RGBA,
		     w, h,
		     0,
		     GL_RGBA,
		     GL_UNSIGNED_BYTE,
		     image->pixels);
	SDL_FreeSurface(image); /* No longer needed */

	return texture;


}


SE_image *SE_image_load(char *path)
{
	
	SE_image *img;
	img = (SE_image*)malloc(sizeof(SE_image));
	
	SDL_Surface *temp; 

	if((temp = IMG_Load(path)) == NULL)
	{
		printf("error, no se pudo cargar la imagen");
	}
	
	img->texture = loadTexture(temp);

	img->w = temp->w;
	img->h = temp->h;
	
	img->x = 0;
	img->y = 0;
	img->z = 0;
	
	img->zoomx = 1.0;
	img->zoomy = 1.0;

	
	img->rotx = 0;
	img->roty = 0;
	img->rotz = 0;

	img->r = 1.0;
	img->g = 1.0;
	img->b = 1.0;

	img->alpha = 1.0;

	img->invert = 0;

	SDL_FreeSurface(temp);
	return img;
}




void SE_image_draw(SE_image *img)
{
	
int x = img->x;
int y = img->y;
int z = img->z;
int zx = img->w*img->zoomx;
int zy = img->h*img->zoomy;



	glLoadIdentity();
 
	enable2d();/*enable ortho coordinates*/

	glTranslatef(x + zx/2,y + zy/2,z);
		
	glRotatef( img->rotx, 1.0f, 0.0f, 0.0f); 
	glRotatef( img->roty, 0.0f, 1.0f, 0.0f);     
	glRotatef( img->rotz, 0.0f, 0.0f, 1.0f);

	glTranslatef(-zx/2,-zy/2,z);

	glColor4f(img->r,img->g,img->b,img->alpha);/*alpha blending*/

	glBindTexture(GL_TEXTURE_2D,img->texture);

	glBegin(GL_QUADS);

		glTexCoord2f(0,0);
		glVertex2f(0,0);    

		glTexCoord2f(1,0);
		glVertex2f(zx,0);
  

		glTexCoord2f(1,1);
		glVertex2f(zx,zy);
    

		glTexCoord2f(0,1);
		glVertex2f(0,zy);
	glEnd();

	disable2d();/*back to perspective coordinates*/

}

void SE_image_segment_draw(SE_image *img,int xtex,int ytex,int wtex,int htex,int posx,int posy,float rotx,float roty,float rotz,int concatenate)
{

int w = img->w;
int h = img->h;
float x1 = (float)xtex/(float)w;
float y1 = (float)ytex/(float)h;
float x2 = (float)(xtex + wtex)/(float)w;
float y2 = (float)(ytex + htex)/(float)h;






	if(concatenate == 0) glLoadIdentity();/*enable same effects for multiple images*/
 
	enable2d();/*enable ortho coordinates*/

	
	glRotatef(rotx, 1.0f, 0.0f, 0.0f); 
	glRotatef(roty, 0.0f, 1.0f, 0.0f);  
	glRotatef(rotz, 0.0f, 0.0f, 1.0f);			

	glTranslatef(posx,posy,0);
		
	glBindTexture(GL_TEXTURE_2D,img->texture);

	glBegin(GL_QUADS);

		glTexCoord2f(x1,y1);
		glVertex2f(0,0);    

		glTexCoord2f(x2,y1);
		glVertex2f(wtex,0);

  

		glTexCoord2f(x2,y2);
		glVertex2f(wtex,htex);
    

		glTexCoord2f(x1,y2);
		glVertex2f(0,htex);
	glEnd();

	disable2d();/*back to perspective coordinates*/

}




void SE_image_clean(SE_image *img)
{

	free(img);
	if(img != 0)
	{
		printf("error, no se pudo borrar puntero de imagen");
	}
	

}

void SE_flip()
{

	SDL_GL_SwapBuffers();/*flipea la escena*/

}

void SE_image_position(SE_image *img,int posx,int posy,int posz)
{

	img->x = posx;
	img->y = posy;
	img->z = posz;

}

void SE_image_size(SE_image *img,int width,int height)
{
	
	img->w = width;
	img->h = height;

}

void SE_image_zoomx(SE_image *img,float zoomx)
{
	
	if(zoomx < 0.0)printf("el zoom no puede ser menor a 0"); 
	img->zoomx = zoomx;

}

void SE_image_zoomy(SE_image *img,float zoomy)
{
	
	if(zoomy < 0.0)printf("el zoom no puede ser menor a 0");
	img->zoomy = zoomy;

}

void SE_image_zoom(SE_image *img,float zoom)
{
	
	SE_image_zoomx(img,zoom);
	SE_image_zoomy(img,zoom);
	
}


void SE_image_rotationx(SE_image *img,GLfloat rotationx)
{

	img->rotx = rotationx;

}
void SE_image_rotationy(SE_image *img,GLfloat rotationy)
{

	img->roty = rotationy;

}
void SE_image_rotationz(SE_image *img,GLfloat rotationz)
{

	img->rotz = rotationz;	

}

void SE_image_rotation(SE_image *img,GLfloat rotationx,GLfloat rotationy,GLfloat rotationz)
{

	SE_image_rotationx(img,rotationx);
	SE_image_rotationy(img,rotationy);
	SE_image_rotationz(img,rotationz);

}


void SE_image_alpha(SE_image *img,float alpha_magnitude)
{
	if(alpha_magnitude < 0.0)alpha_magnitude = 0.0;
	if(alpha_magnitude > 1.0)alpha_magnitude = 1.0;
	img->alpha = alpha_magnitude;

}

void SE_image_tint(SE_image *img,float red,float green,float blue)
{
	img->r = red;
	img->g = green;	
	img->b = blue;

}

void SE_image_light(SE_image *img,float light_intensity)
{
	if((light_intensity < 0.0)||(light_intensity > 1.0))printf("la intensidad de la luz debe estar entre 0 y 1");
	SE_image_tint(img,light_intensity,light_intensity,light_intensity);
	

}

